﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Runtime.Remoting.Messaging;

namespace AEM.Data.BLL.Actions
{
    public static class SerialPorts
    {
        static SerialPorts()
        {
            Query = doQuery;
        }

        /*private static byte[] doQuery(int liftnum)
        {
            try
            {
                List<byte> data = new List<byte>();
                data.Add(0xA1);
                data.Add(0x03);//查询
                data.Add(0x00);
                data.Add(0x00);
                data.Add(byte.Parse(liftnum.ToString()));
                data.Add(0x00);
                data.Add(0x09);
                int checksum = 0;
                for (int i = 1; i < 7; i++)
                {
                    checksum += int.Parse(data[i].ToString("X2"), NumberStyles.HexNumber);
                    if (checksum > 128) checksum %= 128;
                }
                if (checksum > 128) checksum %= 128;
                data.Add(byte.Parse(checksum.ToString()));
                data.Add(0xD1);

                return data.ToArray();
            }
            catch (Exception ex)
            {
                Utils.Log.WriteError(ex.Message, ex);
            }
            return null;
        }*/

        private static byte[] doQuery(int liftnum, Data.Enum.LiftType lifttype)
        {
            try
            {
                List<byte> data = new List<byte>();

                if (lifttype == Data.Enum.LiftType.扶梯)
                {
                    data.Add(byte.Parse(liftnum.ToString()));
                    data.Add(0x03);//查询
                    data.Add(0x00);
                    data.Add(0x00);
                    data.Add(0x00);
                    data.Add(0x16);
                    byte[] crc = Crc(data);
                    data.Add(crc[1]);
                    data.Add(crc[0]);
                }
                else
                {
                    data.Add(0xA1);
                    data.Add(0x03);//查询
                    data.Add(0x00);
                    data.Add(0x00);
                    data.Add(byte.Parse(liftnum.ToString()));
                    data.Add(0x00);
                    data.Add(0x09);
                    int checksum = 0;
                    for (int i = 1; i < 7; i++)
                    {
                        checksum += int.Parse(data[i].ToString("X2"), NumberStyles.HexNumber);
                        if (checksum > 128) checksum %= 128;
                    }
                    if (checksum > 128) checksum %= 128;
                    data.Add(byte.Parse(checksum.ToString()));
                    data.Add(0xD1);
                }
               

                return data.ToArray();
            }
            catch (Exception ex)
            {
                Utils.Log.WriteError(ex.Message, ex);
            }
            return null;
        }

        public static byte[] Crc(List<byte> buffer, int start = 0, int len = 0)
        {
            if (buffer == null || buffer.Count == 0) return null;
            if (start < 0) return null;
            if (len == 0) len = buffer.Count - start;
            int length = start + len;
            if (length > buffer.Count) return null;
            ushort crc = 0xFFFF;// Initial value
            for (int i = start; i < length; i++)
            {
                crc ^= buffer[i];
                for (int j = 0; j < 8; j++)
                {
                    if ((crc & 1) > 0)
                        crc = (ushort)((crc >> 1) ^ 0xA001);// 0xA001 = reverse 0x8005
                    else
                        crc = (ushort)(crc >> 1);
                }
            }
            byte[] ret = BitConverter.GetBytes(crc);
            Array.Reverse(ret);
            return ret;
        }

        /// <summary>
        /// 查询方式：A1 C1	C2	C3	D_1	Len1 Len2	D1
        /// A1：数据头
        /// C1：0x03查询
        /// C2：0x00
        /// C3：0x00
        /// D_1：电梯编号
        /// Len1- len2：len数据长度（len=A1整条数据的字节数，即A1-D1的总字节数）
        /// D1：数据尾
        /// </summary>
        /// <param name="liftnum">电梯编号</param>
        /// <param name="com">COM端口</param>
        /// <returns>成功true，失败false</returns>
        //public static Func<int, byte[]> Query;
        public static Func<int, Data.Enum.LiftType, byte[]> Query;

        /// <summary>
        /// 控制方式：A1 C1 C2 C3 D_1 Len1 Len2 D1
        /// A1：数据头
        /// C1：控制有效0x13，控制解除0x10
        /// C2：控制指令
        /// C3：指令代码
        /// D_1：电梯编号
        /// Len1- Len2： len数据长度（len=A1整条数据的字节数，即A1-D1的总字节数）
        /// D1：数据尾
        /// </summary>
        /// <param name="type">控制类型 true有效,false解除</param>
        /// <param name="liftnum">电梯编号</param>
        /// <param name="port">COM端口</param>
        /// <param name="command">指令代码 0x01呼梯命令,0x02运程锁梯,0x03高峰运行</param>
        /// <param name="floor">呼梯楼层,command==0x01时有效</param>
        public static Action<bool, int, string, byte, int> Regulate;

        public static Action<SerialDataEventArgs> SMSMonitoring;

        public static void RegulateCallback(IAsyncResult tag)
        {
            AsyncResult result = (AsyncResult)tag;
            Action<bool, int, string, byte, int> del = (Action<bool, int, string, byte, int>)result.AsyncDelegate;
            del.EndInvoke(tag);
        }

        public static void SMSCallback(IAsyncResult tag)
        {
            AsyncResult result = (AsyncResult)tag;
            Action<SerialDataEventArgs> del = (Action<SerialDataEventArgs>)result.AsyncDelegate;
            del.EndInvoke(tag);
        }
    }
}
